package networks.Graph.Clustering;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JFrame;

import org.apache.commons.collections15.Transformer;
import org.apache.commons.collections15.map.HashedMap;

import edu.uci.ics.jung.algorithms.cluster.BicomponentClusterer;
import edu.uci.ics.jung.algorithms.cluster.EdgeBetweennessClusterer;
import edu.uci.ics.jung.algorithms.cluster.VoltageClusterer;
import edu.uci.ics.jung.algorithms.cluster.WeakComponentClusterer;
import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.DAGLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.graph.UndirectedGraph;
import edu.uci.ics.jung.graph.event.GraphEvent.Edge;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;


import sun.misc.Regexp;

public class CommunityFinder {
	
	
	HashSet<String> DistictVertices = new HashSet<String>();
	HashedMap<String, ArrayList<String>> Edges = new HashedMap<String, ArrayList<String>>();
	Graph<String, String> ModelGraph ;
	
	public void ReadVertices(String filePath) throws IOException
	{
		//Get a temporary list
		ArrayList<String> AllVertices = new ArrayList<String>();
		
		//Start reader from file
		BufferedReader br = new BufferedReader(new FileReader(filePath));
		
		
	    try {
	        
	        String line = "";

	        
	        while ((line = br.readLine()) != null ) {
	        	
	        	String[] _newVertices = line.split("\\s+");
	        	
	        	//Filling out edges
	        	if(!Edges.containsKey(_newVertices[0]))
	        	{
	        		ArrayList<String> _TempArrayList = new ArrayList<String>();
	        		
	        		
	        		
	        		Edges.put(_newVertices[0], _TempArrayList);
	        	}
	        	
	        	boolean record = true;
	        	if(Edges.containsKey(_newVertices[1]))
	        	{
	        		if(Edges.get(_newVertices[1]).contains(_newVertices[0]))
	        		{
	        			record = false;
	        		}
	        	}
	        	
	        	if(record){
	        		Edges.get(_newVertices[0]).add(_newVertices[1]);
	        	}
	        	
	        	
	        	//Filling out vertices
	        	for (String vertex : _newVertices) {
	        		AllVertices.add(vertex);
				}
	        	
	            
	        }
	        
	    } finally {
	        br.close();
	    }
	    
	    //Turning Vertices into distict values
	    DistictVertices.addAll(AllVertices);
	    
	    InitiateInternalStructures();
		
	}
	
	
	
	protected void InitiateInternalStructures()
	{
		ModelGraph = new edu.uci.ics.jung.graph.OrderedSparseMultigraph<>();
		
		for (String vertex : DistictVertices) {
			ModelGraph.addVertex(vertex);
		}
		
		for (String vertex : Edges.keySet()) {
			ArrayList<String> Connections = Edges.get(vertex);
			for (String target : Connections) {
				ModelGraph.addEdge(vertex+"-"+target, vertex, target);
			}
		}
		
		
		
		
		 System.out.println("The model graph is created");
		 
		 

		 
		 ClusterGraph();

	}
	
	
	private void ClusterGraph() {
		
		edu.uci.ics.jung.algorithms.cluster.EdgeBetweennessClusterer<String, String> Sal = 
				new EdgeBetweennessClusterer<String, String>(50);

		final Collection<Set<String>> Result = Sal.transform(ModelGraph);

		VisualizeResults(Result);
		//System.out.print(ModelGraph.getEdges().toArray()[0].toString().split("\\-")[0]);
	}



	public void VisualizeResults(final Collection<Set<String>> Result)
	{
		
//		edu.uci.ics.jung.algorithms.cluster.WeakComponentClusterer<String, String> Sal = 
//				new WeakComponentClusterer<>();
		

		
		 
		
		
		System.out.print(Result);
		
		
		
		
		 Layout<String, String> layout = new edu.uci.ics.jung.algorithms.layout.ISOMLayout<>(ModelGraph);
		 
		
		 
		 Transformer<String ,Paint> vertexPaint = new Transformer<String ,Paint>() {
			 public Paint transform(String vertex) {
				int index = 0;
				
				 ArrayList<Paint> Colors = new ArrayList<Paint>();
				 Colors.add(Color.BLUE);
				 Colors.add(Color.RED);
				 Colors.add(Color.PINK);
				 Colors.add(Color.LIGHT_GRAY);
				 Colors.add(Color.GREEN);
				 Colors.add(Color.CYAN);
				 Colors.add(Color.BLACK);
				 Colors.add(Color.MAGENTA);
				 Colors.add(Color.YELLOW);
				 Colors.add(Color.WHITE);
				 Colors.add(Color.DARK_GRAY);
				 
				  
				
				 for (Set<String> set : Result) {
					
					 
					 
					 if(set.contains( vertex ))
						 return Colors.get(index);
					 
					 index++;
						
				}
				 
			 return Color.GREEN;
			 }
		 };
		 
		 
		 Transformer<String ,Paint> edgePaint = new Transformer<String ,Paint>() {
			 public Paint transform(String edge) {
				int index = 0;
				
				 
				 String[] vertices = edge.split("\\-");
				 
					
				 ArrayList<Paint> Colors = new ArrayList<Paint>();
				 Colors.add(Color.BLUE);
				 Colors.add(Color.RED);
				 Colors.add(Color.PINK);
				 Colors.add(Color.LIGHT_GRAY);
				 Colors.add(Color.GREEN);
				 Colors.add(Color.CYAN);
				 Colors.add(Color.BLACK);
				 Colors.add(Color.MAGENTA);
				 Colors.add(Color.YELLOW);
				 Colors.add(Color.WHITE);
				 Colors.add(Color.DARK_GRAY);
				
				 for (Set<String> set : Result) {
					
					 
					 
					 if(set.contains( vertices[0] ))
						 if(set.contains(vertices[1]))
							 return Colors.get(index);
					index++; 
					 
						
				}
				 
			 return Color.BLACK;
			 }
		 };

		 
		 
		 layout.setSize(new Dimension(900,900)); // sets the initial size of the space
		 // The BasicVisualizationServer<V,E> is parameterized by the edge types
		 VisualizationViewer<String,String> vv = 
				 new VisualizationViewer<String,String>(layout);
		 vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
		 vv.getRenderContext().setEdgeDrawPaintTransformer(edgePaint);
		 
		 vv.setPreferredSize(new Dimension(1000,1000)); //Sets the viewing area size
		 DefaultModalGraphMouse gm = new DefaultModalGraphMouse();
		 gm.setMode(ModalGraphMouse.Mode.TRANSFORMING);
		 vv.setGraphMouse(gm);
		 
		 
		 JFrame frame = new JFrame("Simple Graph View");
		 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		 frame.getContentPane().add(vv); 
		 frame.pack();
		 frame.setVisible(true); 
	}
	
	 

}
